package com.ft.modules.sys.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ft.common.domain.ResponseInfo;
import com.ft.modules.sys.model.Oder;
import com.ft.modules.sys.model.TUser;
import com.ft.modules.sys.service.OderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author YangJia
 * @since 2021-07-28
 */
@RestController
@RequestMapping("/oder")
@Api(tags = "秒杀测试")
public class OderController {
    @Autowired
    RedisTemplate<String,String> redisTemplate;
    @Autowired
    OderService oderService;
    @ApiOperation(value = "抢购商品",response= ResponseInfo.class)
    @RequestMapping(value = "/qgShoping", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name="userId",value="用户Id",required=true,paramType="form",dataType="Integer"),
            @ApiImplicitParam(name="pderId",value="商品Id",required=true,paramType="form",dataType="Integer"),
    })
    public ResponseEntity<ResponseInfo> qgShoping(Integer userId,Integer pderId){
        ResponseInfo ri = new ResponseInfo();
        String msg = "";
        String lockKey = "lockKey";
        String lockValue = userId+"-"+pderId;
        //加锁
        Boolean success = redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, 10, TimeUnit.SECONDS);
        if(success){
            try {
                msg = server(userId,pderId);
            }finally {
                //释放锁
                releaseLock(lockKey, lockValue);
            }
        }else {
            //不断去获取锁
            while (true){
                Boolean jiaSuo = redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, 10, TimeUnit.SECONDS);
                if(jiaSuo){
                    try {
                        msg  = server(userId,pderId);
                    }finally {
                        //释放锁
                        releaseLock(lockKey, lockValue);
                        break;
                    }
                }
            }
        }
        return ResponseEntity.ok().body(ri.ok(msg));
    }

    /**
     * 订单实现业务层
     * @param userId
     * @param pderId
     * @return
     */
    public String server(Integer userId,Integer pderId){
        //得到库存量
        String orderCount = redisTemplate.opsForValue().get("order-count");
        Integer orderCountInt = 0;
        if(StringUtils.isNotEmpty(orderCount)){
            orderCountInt = Integer.parseInt(orderCount);
            if(orderCountInt <= 0){
               return "暂无库存";
            }
        }
        //生成订单 减少库存量
        boolean inserCount = oderService.save(new Oder(null,userId,pderId));
        if(inserCount){
            redisTemplate.boundValueOps("order-count").increment(-1);
        }else {
            return "订单提交异常";
        }
        System.out.println(String.format("Thread-%d：Success", Thread.currentThread().getId()));
        return "订单提交成功";
    }

    /**
     * 判断释放锁（需要和value做对比，只能释放自己的锁）
     * @param key
     * @param value
     * @return
     */
    private boolean releaseLock(String key, String value){
        String srcValue = redisTemplate.opsForValue().get(key);
        if (StringUtils.isEmpty(srcValue)){
            return true;
        }else if (srcValue.equals(value)){
            redisTemplate.delete(key);
            return true;
        }
        return false;
    }
}
